package com.zhilianbao.leyaogo.utils;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.daimajia.androidanimations.library.BaseViewAnimator;
import com.daimajia.androidanimations.library.YoYo;
import com.zhilianbao.leyaogo.view.widgets.MyRelativeLayout;

/**
 * ClassName: ShopAnimationUtils <br>
 * Description: 购物车动画<br>
 * Author: Cyarie <br>
 * Created: 2016/8/30 17:41 <br>
 * Update Time：<br>
 * Update Description：<br>
 */
public class ShopAnimationUtils {


    /**
     * 加入购物车
     *
     * @param context
     * @param type             0  1 首页
     * @param startView
     * @param endView
     * @param rl
     * @param isSowEndViewAnim
     * @param iAnimEndListener
     */
    public static void addToShoppingCart(Context context, int type, ImageView startView, View endView, MyRelativeLayout rl, boolean isSowEndViewAnim, IAnimEndListener iAnimEndListener) {
        //      一、创造出执行动画的图片---imageView
        //代码new一个imageView，图片资源是上面的startView的图片
        // (这个图片就是执行动画的图片，从开始位置出发，经过一个抛物线（贝塞尔曲线），移动到购物车里)
        final ImageView goods = new ImageView(context);
        goods.setImageDrawable(startView.getDrawable());
        //宽高和startView一样
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(startView.getWidth(), startView.getHeight());
        rl.addView(goods, params);
        //        二、计算动画开始/结束点的坐标的准备工作
        //得到父布局的起始点坐标（用于辅助计算动画开始/结束时的点的坐标）
        int[] parentLocation = new int[2];
        rl.getLocationInWindow(parentLocation);

        //得到商品图片的坐标（用于计算动画开始的坐标）
        int startLoc[] = new int[2];
        startView.getLocationInWindow(startLoc);

        //得到购物车图片的坐标(用于计算动画结束后的坐标)
        int endLoc[] = new int[2];
        endView.getLocationInWindow(endLoc);


        //        三、正式开始计算动画开始/结束的坐标
        //开始掉落的商品的起始点：商品起始点-父布局起始点
        float startX = startLoc[0] - parentLocation[0];
        float startY = startLoc[1] - parentLocation[1];

        //商品掉落后的终点坐标：购物车起始点-父布局起始点-结束View
        float toX;
        float toY;
        if (type == 0) {
            toX = endLoc[0] - parentLocation[0] - endView.getWidth() * 2 / 5;
            toY = endLoc[1] - parentLocation[1] - endView.getHeight() * 2 / 5;
        } else if (type == 1) {
            toX = endLoc[0] - parentLocation[0] - endView.getWidth() / 6;
            toY = endLoc[1] - parentLocation[1] - endView.getHeight() * 6 / 5;
        } else {
            toX = endLoc[0] - parentLocation[0] - endView.getWidth();
            toY = endLoc[1] - parentLocation[1] - endView.getHeight();
        }


        //        四、计算中间动画的插值坐标（贝塞尔曲线）（其实就是用贝塞尔曲线来完成起终点的过程）
        //开始绘制贝塞尔曲线
        Path path = new Path();
        //移动到起始点（贝塞尔曲线的起点）
        path.moveTo(startX, startY);
        //使用二次贝塞尔曲线：注意第一个起始坐标越大，贝塞尔曲线的横向距离就会越大，一般按照下面的式子取即可
        path.quadTo((startX + toX) / 2, startY, toX, toY);
        //mPathMeasure用来计算贝塞尔曲线的曲线长度和贝塞尔曲线中间插值的坐标，
        // 如果是true，path会形成一个闭环
        PathMeasure mPathMeasure = new PathMeasure(path, false);

        //★★★属性动画实现（从0到贝塞尔曲线的长度之间进行插值计算，获取中间过程的距离值）
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength());
        //缩放
        ValueAnimator valueAnimator1;
        ValueAnimator valueAnimator2;

        if (type == 2) {
            //缩放
            valueAnimator1 = ObjectAnimator.ofFloat(goods, "scaleX", 0.5f, 0.15f);
            valueAnimator2 = ObjectAnimator.ofFloat(goods, "scaleY", 0.5f, 0.15f);
        } else {
            //缩放
            valueAnimator1 = ObjectAnimator.ofFloat(goods, "scaleX", 0.8f, 0.3f);
            valueAnimator2 = ObjectAnimator.ofFloat(goods, "scaleY", 0.8f, 0.3f);
        }
        // 匀速线性插值器
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(800);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());

        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                rl.setPass(false);
            }

            //当动画结束后：
            @Override
            public void onAnimationEnd(Animator animation) {
                // 把移动的图片imageView从父布局里移除
                rl.removeView(goods);
                rl.setPass(true);
                if (isSowEndViewAnim) {
                    YoYo.with(new ScaleUpAnimator())
                            .duration(500)
                            .playOn(endView);
                }
                if (iAnimEndListener != null)
                    iAnimEndListener.onAnimEnd();
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            /**
             * 贝塞尔曲线中间过程的点的坐标
             */
            private float[] mCurrentPosition = new float[2];

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 当插值计算进行时，获取中间的每个值，
                // 这里这个值是中间过程中的曲线长度（下面根据这个值来得出中间点的坐标值）
                float value = (Float) animation.getAnimatedValue();
                // ★★★★★获取当前点坐标封装到mCurrentPosition
                // boolean getPosTan(float distance, float[] pos, float[] tan) ：
                // 传入一个距离distance(0<=distance<=getLength())，然后会计算当前距
                // 离的坐标点和切线，pos会自动填充上坐标，这个方法很重要。
                mPathMeasure.getPosTan(value, mCurrentPosition, null);//mCurrentPosition此时就是中间距离点的坐标值
                // 移动的商品图片（动画图片）的坐标设置为该中间点的坐标
                goods.setTranslationX(mCurrentPosition[0]);
                goods.setTranslationY(mCurrentPosition[1]);
            }
        });
        //      五、 开始执行动画
        animatorSet.playTogether(valueAnimator, valueAnimator1, valueAnimator2);
        animatorSet.start();
    }

    /**
     * 动画结束监听
     */
    public interface IAnimEndListener {
        void onAnimEnd();
    }

    public static class ScaleUpAnimator extends BaseViewAnimator {
        @Override
        public void prepare(View target) {
            getAnimatorAgent().playTogether(
                    com.nineoldandroids.animation.ObjectAnimator.ofFloat(target, "scaleX", 0.8f, 1f, 1.4f, 1.2f, 1),
                    com.nineoldandroids.animation.ObjectAnimator.ofFloat(target, "scaleY", 0.8f, 1f, 1.4f, 1.2f, 1)
            );
        }
    }

}
